Skip to content

Mobile App Insights: small slice (Mac Catalyst)#165

Draft
davidortinau wants to merge 4 commits intomainfrom
squad/mobile-appinsights-slice
Draft

Mobile App Insights: small slice (Mac Catalyst)#165
davidortinau wants to merge 4 commits intomainfrom
squad/mobile-appinsights-slice

Conversation

@davidortinau
Copy link
Copy Markdown
Owner

Ships the first-increment (~3 hour) mobile Application Insights slice per Captain's path 1 go approval. Wires Azure.Monitor.OpenTelemetry.Exporter into the existing MAUI OTel pipeline, subscribes to MauiExceptions.UnhandledException, and embeds the connection string in appsettings.Production.json (write-only ingestion key — embedding is the documented pattern; per the decisions memo wash-mobile-appinsights-answers).

In scope

  • Azure resource sstudio-mobile-ai in rg-sstudio-prod, workspace-linked to law-3ovvqiybthkb6, daily cap 0.5 GB.
  • Azure.Monitor.OpenTelemetry.Exporter 1.7.0 added to SentenceStudio.MauiServiceDefaults. Bumped OpenTelemetry.Extensions.Hosting / Exporter.OTLP / Instrumentation.Http to 1.15.x to satisfy Azure Monitor's transitive floor.
  • cloud_RoleName set explicitly via ResourceBuilder.AddService("SentenceStudio.Mobile.<DeviceInfo.Platform>").
  • SentenceStudioAppBuilder.InitializeApp subscribes once to MauiExceptions.UnhandledExceptionILogger.LogCritical → best-effort ForceFlush(3000) on all three OTel providers before the process dies.
  • appsettings.Production.json updated with AzureMonitor:ConnectionString.
  • Fixed pre-existing Release-build break: MacCatalyst/MauiProgram.cs had unguarded using Microsoft.Maui.DevFlow.* even though those packages are Condition='$(Configuration)'=='Debug'. Wrapped the usings in #if DEBUG.

Out of scope (deferred to full plan)

  • Blazor WebView JS error bridge (window.onerror, unhandledrejection)
  • Android / iOS linker preserve directives for Release link-time trimming
  • PrivacyInfo.xcprivacy (Captain confirmed no App Store submission planned)
  • Windows head, marketing site
  • Custom telemetry processors / sampling / session replay / live metrics

Validation

Built Release Mac Catalyst, launched with SENTENCESTUDIO_CRASH_TEST=1, temp thread threw InvalidOperationException 10s after launch. Waited 4 minutes. KQL query:

exceptions
| where timestamp > ago(15m)
| where cloud_RoleName contains "SentenceStudio"
| project timestamp, type, outerMessage, cloud_RoleName, operation_Id
| order by timestamp desc

Result (truncated):

timestamp type outerMessage cloud_RoleName
2026-04-20T03:09:14Z System.InvalidOperationException AppInsights pipeline validation (wash: squad/mobile-appinsights-slice) SentenceStudio.Mobile.MacCatalyst
2026-04-20T03:09:04Z System.InvalidOperationException Model building is not supported when publishing with NativeAOT… SentenceStudio.Mobile.MacCatalyst
2026-04-20T03:09:04Z System.InvalidOperationException HelpKit could not select a presenter automatically… SentenceStudio.Mobile.MacCatalyst

The forced exception (AppInsights pipeline validation…) is there, plus bonus evidence the pipeline is already catching caught-and-logged exceptions from startup code paths (EF NativeAOT model-build, HelpKit presenter). cloud_RoleName is correct. Temp validation code reverted before commit.

operation_Id is empty because we throw from a bare Thread, not inside an OTel-instrumented activity. Real crashes inside an HttpClient span will populate it and correlate to the API once the server-side companion ships.

Secret management

Committed the connection string to appsettings.Production.json (which is already a tracked file containing service-discovery endpoints). Rationale, per .squad/decisions.md wash-mobile-appinsights-answers:

  • InstrumentationKey is write-only: it authorizes ingestion push; it cannot read telemetry or touch any other Azure resource.
  • Microsoft's documented pattern for mobile/desktop/JS clients is to ship it in the bundle.
  • Worst case is fake-telemetry spam, bounded by the 0.5 GB/day ingestion cap we set.
  • All "secure" alternatives (fetch-at-startup, per-user keys, Key Vault) are strictly worse for mobile — chicken-and-egg if the API is down, or require an Azure identity the app doesn't have.

If Captain prefers an env-var / non-committed override path later, that is easy to add (the config system reads env vars already).

Follow-ups before full rollout

  • Server-side Azure Monitor exporter in SentenceStudio.Api so W3C traceparent correlates mobile → API spans.
  • Blazor WebView JS bridge.
  • Android/iOS linker preserve + Android Release smoke test.
  • iOS device smoke test on DX24 (Release).
  • Windows head.

Resource

  • App Insights: /subscriptions/a25bc5f2-e641-47b9-89a8-5e5fd428d9d6/resourceGroups/rg-sstudio-prod/providers/microsoft.insights/components/sstudio-mobile-ai
  • AppId: 74e94530-d17f-404a-8726-b7266724b70f
  • Daily cap: 0.5 GB, notifications on cap

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

davidortinau and others added 4 commits April 19, 2026 17:37
- Merge wash-observability.md from decisions/inbox/ to decisions.md
- Delete inbox file
- Add orchestration log: 2026-04-19T22:36:52Z-wash.md
- Add session log: 2026-04-19-azure-error-visibility.md
- Append observability note to wash/history.md for cross-agent visibility

Audit outcome: Container logs flow correctly; App Insights unconfigured; no global exception handler; AI endpoints silent on failures; /health unmapped. Wash proposes four-part fix (App Insights, exception middleware, AI endpoint logging, /health) awaiting Captain approval (~1 day).

Immediate workaround provided: CLI tail + KQL query against law-3ovvqiybthkb6.
- Merge wash-mobile-observability.md from inbox → decisions.md
- Update decisions.md with full mobile App Insights plan
- Append cross-agent note to Kaylee history (Blazor JS error bridge opportunity)
- Update Wash history with planning context

Awaiting Captain decisions on:
1. One vs. two App Insights resources
2. Connection string embedding OK
3. App Store submission timeline (PrivacyInfo.xcprivacy)
4. Marketing site scope

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Orchestration log: 2026-04-20T02-42-17Z-wash.md
  * Wash answered Captain's 3 follow-up questions on mobile observability
  * Findings: ONE App Insights resource (shared MAUI+API), embed connection string, reject TinyInsights.Maui

- Session log: 2026-04-20T02-42-17Z-mobile-appinsights-qa.md (brief summary)

- Merged decision inbox → decisions.md (now 54.5KB)
  * wash-mobile-appinsights-answers.md merged with full QA rationale
  * Deleted inbox file after merge

- Tasks 4-7: no-op (no cross-agent work, no archiving needed, history.md already summarized)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wires Azure Monitor OpenTelemetry exporter into the existing MAUI OTel
pipeline and subscribes to MauiExceptions.UnhandledException so unhandled
crashes land in Application Insights.

Changes:
- MauiServiceDefaults: add Azure.Monitor.OpenTelemetry.Exporter 1.7.0,
  bump OpenTelemetry.Extensions.Hosting/Exporter.OTLP/Instrumentation.Http
  to 1.15.x to satisfy the transitive floor. AddAzureMonitor{Log,Metric,
  Trace}Exporter is gated on #if !DEBUG + a non-empty connection string so
  simulator/dev runs stay silent. Sets a stable service name
  SentenceStudio.Mobile.<Platform> so App Insights cloud_RoleName
  identifies the client clearly.
- SentenceStudioAppBuilder.InitializeApp: one subscriber on
  MauiExceptions.UnhandledException that critical-logs the exception and
  best-effort ForceFlush's LoggerProvider/TracerProvider/MeterProvider
  (3s budget) before the process dies.
- appsettings.Production.json: AzureMonitor:ConnectionString for the
  sstudio-mobile-ai App Insights resource in rg-sstudio-prod.
- MacCatalyst/MauiProgram.cs: #if DEBUG guard the DevFlow usings so
  Release builds don't fail on the debug-only package references
  (pre-existing bug, unblocks Release validation).

OUT of scope (deferred to full plan): Blazor WebView JS bridge, Android
linker preserve, iOS linker preserve, PrivacyInfo.xcprivacy, Windows,
custom processors.

Validated on Mac Catalyst Release with a forced InvalidOperationException;
record appeared in App Insights within ~5 minutes with cloud_RoleName=
SentenceStudio.Mobile.MacCatalyst. Server-side companion still pending
so client spans will be orphan until the API also emits to App Insights.

Refs: .squad/decisions.md wash-mobile-observability, wash-mobile-appinsights-answers

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant